<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>定时任务</title>
    <script src="/js/vue/vue.js"></script>
    <script src="/js/vue/axios.js"></script>
    <script src="/js/vue/element-ui.js"></script>
    <script src="/js/util.js"></script>
    <style>
        @import url("/css/vue/element-ui.css");
        .el-message {
            min-width: 100px !important;
            max-width: 80% !important;
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
        }

        :root {
            --primary: #4361ee;
            --secondary: #3f37c9;
            --success: #4cc9f0;
            --danger: #f72585;
            --warning: #f8961e;
            --light: #f8f9fa;
            --dark: #212529;
            --background: #f0f2f5;
            --card-bg: #ffffff;
            --text-primary: #333333;
            --text-secondary: #6c757d;
            --border: #e0e0e0;
        }

        body {
            background-color: var(--background);
            color: var(--text-primary);
            line-height: 1.6;
            padding-bottom: 80px;
        }

        .container {
            max-width: 100%;
            padding: 0 15px;
        }

        /* 头部样式 */
        header {
            background: linear-gradient(135deg, var(--primary), var(--secondary));
            color: white;
            padding: 20px 15px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            position: sticky;
            top: 0;
            z-index: 100;
        }

        .header-content {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .logo {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .logo i {
            font-size: 24px;
        }

        .logo h1 {
            font-size: 20px;
            font-weight: 600;
        }

        .nav-dropdown {
            position: absolute;
            right: 15px;
            display: inline-block;
            margin-right: 15px;
        }

        .nav-dropdown select {
            background-color: rgba(255, 255, 255, 0.2);
            color: white;
            border: 1px solid rgba(255, 255, 255, 0.3);
            border-radius: 5px;
            padding: 8px 12px;
            font-size: 14px;
            appearance: none;
            -webkit-appearance: none;
            -moz-appearance: none;
            cursor: pointer;
            padding-right: 30px;
            outline: none;
        }

        .nav-dropdown select option {
            background-color: var(--primary);
            color: white;
        }

        .nav-dropdown::after {
            content: "▼";
            font-size: 10px;
            color: white;
            position: absolute;
            right: 10px;
            top: 50%;
            transform: translateY(-50%);
            pointer-events: none;
        }

        /* 主内容区 */
        .main-content {
            padding: 20px 0;
        }

        .section-title {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding: 0 10px;
        }

        .section-title h2 {
            font-size: 18px;
            font-weight: 600;
        }

        .btn {
            background-color: var(--primary);
            color: white;
            border: none;
            border-radius: 50px;
            padding: 10px 20px;
            font-size: 14px;
            font-weight: 500;
            display: flex;
            align-items: center;
            gap: 8px;
            cursor: pointer;
            transition: all 0.3s ease;
            box-shadow: 0 4px 6px rgba(67, 97, 238, 0.2);
        }

        .btn:hover {
            background-color: var(--secondary);
            transform: translateY(-2px);
        }

        .btn i {
            font-size: 14px;
        }

        /* 任务列表 */
        .task-list {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }

        .task-item {
            background-color: var(--card-bg);
            border-radius: 12px;
            padding: 16px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
            transition: transform 0.3s ease;
        }

        .task-item:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
        }

        .task-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 8px;
        }

        .task-title {
            font-weight: 600;
            font-size: 16px;
        }

        .task-function {
            font-size: 12px;
            background-color: var(--light);
            padding: 4px 8px;
            border-radius: 4px;
            color: var(--warning);
        }

        .task-details {
            display: flex;
            flex-direction: column;
            gap: 8px;
            font-size: 14px;
            color: var(--text-secondary);
        }

        .task-time {
            display: flex;
            align-items: center;
            gap: 4px;
        }

        .task-content {
            margin-top: 8px;
            padding: 8px;
            background-color: var(--light);
            border-radius: 4px;
            font-family: 'Consolas', monospace;
            font-size: 13px;
            max-height: 60px;
            overflow: hidden;
            text-overflow: ellipsis;
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
        }

        .task-actions {
            display: flex;
            justify-content: flex-end;
            gap: 8px;
            margin-top: 12px;
        }

        .task-action-btn {
            padding: 6px 12px;
            border-radius: 4px;
            font-size: 12px;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .task-action-btn.edit {
            background-color: var(--light);
            color: var(--primary);
            border: 1px solid var(--primary);
        }

        .task-action-btn.delete {
            background-color: var(--light);
            color: var(--danger);
            border: 1px solid var(--danger);
        }

        .task-action-btn:hover {
            opacity: 0.8;
        }

        /* 模态框 */
        .modal {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 1000;
            opacity: 0;
            visibility: hidden;
            transition: all 0.3s ease;
        }

        .modal.active {
            opacity: 1;
            visibility: visible;
        }

        .modal-content {
            background-color: var(--card-bg);
            border-radius: 16px;
            width: 90%;
            max-width: 500px;
            max-height: 80vh;
            display: flex;
            flex-direction: column;
            transform: translateY(20px);
            transition: transform 0.3s ease;
        }

        .modal.active .modal-content {
            transform: translateY(0);
        }

        .modal-header {
            padding: 20px;
            border-bottom: 1px solid var(--border);
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-shrink: 0; /* 防止头部被压缩 */
        }

        .modal-title {
            font-size: 18px;
            font-weight: 600;
        }

        .close-btn {
            background: none;
            border: none;
            font-size: 20px;
            color: var(--text-secondary);
            cursor: pointer;
        }

        .modal-body {
            padding: 20px;
            overflow-y: auto; /* 只有内容区域可以滚动 */
            flex-grow: 1; /* 内容区域占据剩余空间 */
        }

        .modal-footer {
            padding: 20px;
            border-top: 1px solid var(--border);
            display: flex;
            gap: 15px;
            flex-shrink: 0; /* 防止底部被压缩 */
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 500;
            font-size: 14px;
        }

        .form-control {
            width: 100%;
            padding: 12px 15px;
            border: 1px solid var(--border);
            border-radius: 10px;
            font-size: 15px;
            transition: border 0.3s ease;
        }

        .form-control:focus {
            outline: none;
            border-color: var(--primary);
        }

        .code-editor {
            width: 100%;
            min-height: 200px;
            padding: 12px;
            border: 1px solid var(--border);
            border-radius: 10px;
            font-family: 'Consolas', monospace;
            font-size: 14px;
            resize: vertical;
        }

        .time-inputs {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin: 12px 0;
        }

        .time-input {
            flex: 1;
            min-width: 60px;
        }

        .time-label {
            font-size: 12px;
            text-align: left;
            color: var(--text-secondary);
            margin-bottom: 4px;
        }

        .week-buttons {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            margin: 12px 0;
        }

        .week-button {
            flex: 1;
            min-width: 40px;
            padding: 8px;
            text-align: center;
            border: 1px solid var(--border);
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .week-button.active {
            background-color: var(--primary);
            color: white;
            border-color: var(--primary);
        }

        .modal-footer {
            padding: 20px;
            border-top: 1px solid var(--border);
            display: flex;
            gap: 15px;
        }

        .btn-cancel {
            background-color: var(--light);
            color: var(--text-primary);
            flex: 1;
        }

        .btn-submit {
            background-color: var(--primary);
            color: white;
            flex: 1;
        }

        .btn-debug {
            background-color: var(--warning);
            color: white;
            flex: 1;
        }

        /* 响应式调整 */
        @media (max-width: 480px) {
            .header-content {
                flex-direction: column;
                align-items: flex-start;
                gap: 10px;
            }

            .logo h1 {
                font-size: 18px;
            }

            .time-inputs {
                flex-direction: column;
                gap: 8px;
            }

            .time-input {
                width: 100%;
            }
        }

        /* 动画效果 */
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .task-item {
            animation: fadeIn 0.4s ease forwards;
        }

        /* 浮动按钮 */
        .floating-btn {
            position: fixed;
            bottom: 20px;
            right: 20px;
            width: 56px;
            height: 56px;
            border-radius: 50%;
            background-color: var(--primary);
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
            cursor: pointer;
            z-index: 100;
            transition: all 0.3s ease;
        }

        .floating-btn:hover {
            transform: translateY(-2px) scale(1.05);
            background-color: var(--secondary);
        }

        /* 空状态 */
        .empty-state {
            text-align: center;
            padding: 40px 20px;
            color: var(--text-secondary);
        }

        .empty-state i {
            font-size: 48px;
            margin-bottom: 16px;
            opacity: 0.5;
        }

        .empty-state h3 {
            font-size: 16px;
            margin-bottom: 8px;
        }

        .empty-state p {
            font-size: 14px;
        }
    </style>
</head>
<body>
<div id="app">
    <header>
        <div class="container">
            <div class="header-content">
                <div class="logo">
                    <h1>Coder-nav</h1>
                </div>
                <div class="nav-dropdown">
                    <select v-model="currentPage" @change="navigateToPage">
                        <option value="/">🍡&emsp;导航主页</option>
                        <option value="/memo">📌&emsp;记事本</option>
                        <option value="/cash">💰&emsp;记账本</option>
                        <option value="/page">🌈&emsp;动态页面</option>
                        <option value="/task">⏱️&emsp;定时任务</option>
                        <option value="/setting">⚙️&emsp;个人设置</option>
                        <option value="/readme">📖&emsp;帮助手册</option>
                        <option value="/doc.html">🛠️&emsp;接口文档</option>
                    </select>
                </div>
            </div>
        </div>
    </header>

    <div class="container">
        <div class="main-content">
            <div class="section-title">
                <h2>定时任务列表</h2>
                <button class="btn" @click="openAddModal">
                    <i class="fas fa-plus"></i>
                    <span>新增任务</span>
                </button>
            </div>

            <div class="task-list">
                <div v-if="tableData.length === 0" class="empty-state">
                    <i class="fas fa-clock"></i>
                    <h3>暂无定时任务</h3>
                    <p>点击右上角按钮添加新的定时任务</p>
                </div>

                <div v-for="task in tableData" :key="task.id" class="task-item">
                    <div class="task-header">
                        <div class="task-title">{{ task.title }}</div>
                        <div class="task-function">{{ task.actionFunctionDesc }}</div>
                    </div>
                    <div class="task-details">
                        <div class="task-time">
                            <i class="fas fa-clock"></i>
                            <span>{{ task.actionTime || '未设置执行时间' }}</span>
                        </div>
                        <div class="task-time" v-if="task.nextActionTime">
                            <i class="fas fa-redo"></i>
                            <span>下次执行: {{ task.nextActionTime }}</span>
                        </div>
                    </div>
                    <div class="task-content" v-html="formatContent(task.context)"></div>
                    <div class="task-actions">
                        <div class="task-action-btn edit" @click="editTask(task.id)">编辑</div>
                        <div class="task-action-btn delete" @click="deleteTask(task.id)">删除</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 新增/编辑任务模态框 -->
    <div class="modal" :class="{ active: showModal }">
        <div class="modal-content">
            <div class="modal-header">
                <h3 class="modal-title">{{ modalTitle }}</h3>
                <button class="close-btn" @click="closeModal">&times;</button>
            </div>
            <div class="modal-body">
                <form id="taskForm">
                    <div class="form-group">
                        <label for="taskTitle">任务标题</label>
                        <input type="text" id="taskTitle" v-model="infoTitle" class="form-control" placeholder="请输入任务标题" required>
                    </div>

                    <div class="form-group">
                        <label for="taskFunction">执行方法</label>
                        <select id="taskFunction" v-model="infoActionFunction" class="form-control" required>
                            <option value="">请选择执行方法</option>
                            <option v-for="item in functionList" :value="item.value">{{ item.key }}</option>
                        </select>
                    </div>

                    <div class="form-group">
                        <label for="taskSort">排序</label>
                        <input type="number" id="taskSort" v-model="infoSort" class="form-control" placeholder="请输入排序" min="0" required>
                    </div>

                    <div class="form-group">
                        <label for="taskTime">执行时间</label>
                        <input type="datetime-local" id="taskTime" v-model="infoactionTime" class="form-control">
                    </div>

                    <div class="form-group">
                        <label for="taskContent">任务内容</label>
                        <textarea
                                id="taskContent"
                                v-model="infoContext"
                                class="code-editor"
                                placeholder="请输入任务内容..."
                                style="white-space: pre;"
                        ></textarea>
                    </div>

                    <div class="form-group">
                        <label>下次执行时间增量</label>
                        <div class="time-inputs">
                            <div class="time-input">
                                <div class="time-label">年</div>
                                <input type="number" v-model="infoYear" class="form-control" min="0">
                            </div>
                            <div class="time-input">
                                <div class="time-label">月</div>
                                <input type="number" v-model="infoMonth" class="form-control" min="0">
                            </div>
                            <div class="time-input">
                                <div class="time-label">日</div>
                                <input type="number" v-model="infoDay" class="form-control" min="0">
                            </div>
                            <div class="time-input">
                                <div class="time-label">时</div>
                                <input type="number" v-model="infoHour" class="form-control" min="0">
                            </div>
                            <div class="time-input">
                                <div class="time-label">分</div>
                                <input type="number" v-model="infoMinute" class="form-control" min="0">
                            </div>
                        </div>
                    </div>

                    <div class="form-group">
                        <label>适用星期</label>
                        <div class="week-buttons">
                            <div
                                    class="week-button"
                                    :class="{ active: week0 }"
                                    @click="week0 = !week0"
                            >日</div>
                            <div
                                    class="week-button"
                                    :class="{ active: week1 }"
                                    @click="week1 = !week1"
                            >一</div>
                            <div
                                    class="week-button"
                                    :class="{ active: week2 }"
                                    @click="week2 = !week2"
                            >二</div>
                            <div
                                    class="week-button"
                                    :class="{ active: week3 }"
                                    @click="week3 = !week3"
                            >三</div>
                            <div
                                    class="week-button"
                                    :class="{ active: week4 }"
                                    @click="week4 = !week4"
                            >四</div>
                            <div
                                    class="week-button"
                                    :class="{ active: week5 }"
                                    @click="week5 = !week5"
                            >五</div>
                            <div
                                    class="week-button"
                                    :class="{ active: week6 }"
                                    @click="week6 = !week6"
                            >六</div>
                        </div>
                    </div>

                    <div class="form-group">
                        <label>参考时间</label>
                        <div style="padding: 8px; background-color: var(--light); border-radius: 6px;">
                            <pre>{{ infoNextActionTime || '无' }}</pre>
                        </div>
                    </div>
                </form>
            </div>
            <div class="modal-footer">
                <button class="btn btn-cancel" @click="closeModal">取消</button>
                <button class="btn btn-debug" @click="debugTask">测试</button>
                <button class="btn btn-submit" @click="saveTask">保存</button>
            </div>
        </div>
    </div>

</div>

<script>
    new Vue({
        el: '#app',
        data: {
            tableData: [],
            showModal: false,
            editing: false,
            currentPage: '/task',
            // 详情
            infoId: null,
            infoUserId: null,
            infoactionTime: null,
            infoTitle: null,
            infoUrl: null,
            infoContext: null,
            infoSort: 0,
            infoYear: 0,
            infoMonth: 0,
            infoDay: 0,
            infoHour: 0,
            infoMinute: 0,
            infoActionFunction: null,
            infoNextActionTime: '',
            // 星期选择
            week0: false,
            week1: false,
            week2: false,
            week3: false,
            week4: false,
            week5: false,
            week6: false,
            // 方法列表
            functionList: [],
            // 分页
            pageIndex: 1,
            pageSize: 10,
            totalCount: 0
        },
        computed: {
            modalTitle() {
                return this.editing ? "编辑定时任务" : "新增定时任务";
            }
        },
        mounted() {
            this.checkToken();
        },
        methods: {
            formatContent(content) {
                if (!content) return '';
                // 简单处理内容显示，实际可以根据需要添加Markdown解析
                return content.length > 100 ? content.substring(0, 100) + '...' : content;
            },
            openAddModal() {
                this.infoId = null;
                this.infoUserId = null;
                this.infoactionTime = null;
                this.infoTitle = null;
                this.infoUrl = null;
                this.infoContext = null;
                this.infoSort = 0;
                this.infoYear = 0;
                this.infoMonth = 0;
                this.infoDay = 0;
                this.infoHour = 0;
                this.infoMinute = 0;
                this.infoActionFunction = null;
                this.infoNextActionTime = '';
                this.week0 = false;
                this.week1 = false;
                this.week2 = false;
                this.week3 = false;
                this.week4 = false;
                this.week5 = false;
                this.week6 = false;
                this.editing = false;
                this.showModal = true;
            },
            editTask(id) {
                this.getInfo(id);
                this.editing = true;
                this.showModal = true;
            },
            deleteTask(id) {
                if (confirm('确定要删除这个定时任务吗？')) {
                    this.del(id);
                }
            },
            closeModal() {
                this.showModal = false;
                this.editing = false;
            },
            saveTask() {
                this.save(0);
                this.closeModal();
            },
            debugTask() {
                this.save(1);
            },
            navigateToPage() {
                if (this.currentPage && this.currentPage !== window.location.pathname) {
                    window.location.href = this.currentPage;
                }
            },
            // 检查Token
            checkToken() {
                localStorage.setItem('jump', window.location.href);
                axios.get('/login/checkToken', {
                    params: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    if(!response.data.data) {
                        localStorage.setItem('token', '');
                        window.location.href = '/login';
                        return;
                    }
                    this.getFunctionList();
                    this.getPage();
                });
            },
            // 分页
            getPage() {
                axios.post('/task/getPage', {
                    pageIndex: this.pageIndex,
                    pageSize: this.pageSize,
                }, {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.tableData = response.data.data.data;
                    this.pageIndex = response.data.data.pageIndex;
                    this.pageSize = response.data.data.pageSize;
                    this.totalCount = response.data.data.totalCount;
                }).catch((error) => {
                    console.error(error);
                });
            },
            // 获取方法列表
            getFunctionList() {
                axios.get('/task/getFunctionList', {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.functionList = response.data.data;
                });
            },
            // 保存/编辑
            save(type) {
                const weeks = [];
                if(this.week0) weeks.push('0');
                if(this.week1) weeks.push('1');
                if(this.week2) weeks.push('2');
                if(this.week3) weeks.push('3');
                if(this.week4) weeks.push('4');
                if(this.week5) weeks.push('5');
                if(this.week6) weeks.push('6');

                const actionTime = this.infoactionTime ? formatDate(new Date(this.infoactionTime)) : null;

                const url = type === 0 ? '/task/save' : '/task/debug';

                if (type === 1) {
                    // 显示加载中
                    this.$loading = true;
                }

                axios.post(url, {
                    id: this.infoId,
                    title: this.infoTitle,
                    url: this.infoUrl,
                    context: this.infoContext,
                    actionFunction: this.infoActionFunction,
                    sort: this.infoSort,
                    year: this.infoYear,
                    month: this.infoMonth,
                    day: this.infoDay,
                    hour: this.infoHour,
                    minute: this.infoMinute,
                    weeks: weeks.join(','),
                    actionTime: actionTime,
                }, {
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    if(response.data.code === 200) {
                        if(type === 0) {
                            this.getPage();
                            if (this.infoId) {
                                this.getInfo(this.infoId);
                            }
                            this.$message.info('保存成功');
                        } else {
                            this.$message.info('测试成功，消息已推送');
                        }
                    } else {
                        this.$message.error(response.data.msg);
                    }
                }).catch((error) => {
                    console.error(error);
                    this.$message.error('操作失败');
                }).finally(() => {
                    if (type === 1) {
                        this.$loading = false;
                    }
                });
            },
            // 删除
            del(id) {
                axios.delete('/task/delete', {
                    params: {
                        id: id
                    },
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    this.getPage();
                }).catch((error) => {
                    console.error(error);
                    this.$message.error('删除失败');
                });
            },
            // 详情
            getInfo(id) {
                axios.get('/task/getInfo', {
                    params: {
                        id: id
                    },
                    headers: {
                        token: localStorage.getItem('token')
                    }
                }).then((response) => {
                    const data = response.data.data;
                    this.infoId = data.id;
                    this.infoUserId = data.userId;
                    this.infoactionTime = data.actionTime;
                    this.infoUrl = data.url;
                    this.infoTitle = data.title;
                    this.infoContext = data.context;
                    this.infoActionFunction = data.actionFunction;
                    this.infoSort = data.sort;
                    this.infoYear = data.year;
                    this.infoMonth = data.month;
                    this.infoDay = data.day;
                    this.infoHour = data.hour;
                    this.infoMinute = data.minute;
                    this.infoNextActionTime = data.nextActionTime;

                    // 设置星期选择
                    if(data.weeks) {
                        const weeks = data.weeks.split(',');
                        this.week0 = weeks.includes('0');
                        this.week1 = weeks.includes('1');
                        this.week2 = weeks.includes('2');
                        this.week3 = weeks.includes('3');
                        this.week4 = weeks.includes('4');
                        this.week5 = weeks.includes('5');
                        this.week6 = weeks.includes('6');
                    } else {
                        this.week0 = false;
                        this.week1 = false;
                        this.week2 = false;
                        this.week3 = false;
                        this.week4 = false;
                        this.week5 = false;
                        this.week6 = false;
                    }
                }).catch((error) => {
                    console.error(error);
                    this.$message.error('获取任务详情失败');
                });
            }
        }
    });
</script>
</body>
</html>